package htmlbrowser;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;

import htmlbrowser.domtree.HTMLDOMTreeFrame;

public class HTMLBrowserFrame extends JFrame
		implements ActionListener, HyperlinkListener {
	private JTextField addressField = new JTextField();
	private JEditorPane browserPane = new JEditorPane();
	private JLabel statusLabel = new JLabel();
	private JFileChooser fc = new JFileChooser();
	public HTMLDOMTreeFrame domTreeFrame = new HTMLDOMTreeFrame();
	
	public HTMLBrowserFrame() {
		initComponents();
		browserPane.addHyperlinkListener(this);
	}
	
    /** This method is called from within the constructor to
     * initialize the form.
     */
    private void initComponents() {
    	setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    	setTitle("HTML Browser");
    	
    	JLabel addressLabel = new JLabel("address:");
		JButton goButton = new JButton("Go");
		goButton.addActionListener(this);
		
    	//Create GroupLayout for addressPanel
    	JPanel addressPanel = new JPanel();
    	GroupLayout layout = new GroupLayout(addressPanel);
    	addressPanel.setLayout(layout);
    	
    	//Create a sequential group for the horizontal axis
    	SequentialGroup hGroup = layout.createSequentialGroup();
    	
    	hGroup.addContainerGap(10, 10);
    	hGroup.addComponent(addressLabel);
    	hGroup.addContainerGap(10, 10);
    	hGroup.addComponent(addressField, GroupLayout.DEFAULT_SIZE, 321, Short.MAX_VALUE);
    	hGroup.addContainerGap(10, 10);
    	hGroup.addComponent(goButton);
    	hGroup.addContainerGap(10, 10);
    	
    	//Create the horizontal group
    	layout.setHorizontalGroup(hGroup);
    	
    	//Create a sequential group for the vertical axis
    	SequentialGroup vGroup = layout.createSequentialGroup();
    	
    	ParallelGroup v1 = layout.createParallelGroup(GroupLayout.Alignment.BASELINE);
    	
    	v1.addComponent(addressLabel);
    	v1.addComponent(addressField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE);
    	v1.addComponent(goButton);
    	
    	vGroup.addGap(5);
    	vGroup.addGroup(v1);
    	vGroup.addGap(5);
    	
    	//Create the vertical group
    	layout.setVerticalGroup(vGroup);
    	//pack();
    	
    	browserPane.setEditable(false);
		browserPane.setEditorKit(Main.editorKit);
		browserPane.setEditorKitForContentType("HTML", Main.editorKit);
		
		JScrollPane browserScrollPane = new JScrollPane(browserPane);
		
		statusLabel.setPreferredSize(new Dimension(0, 25));
		
		Container contentPane = getContentPane();
		//mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
		contentPane.add(addressPanel, BorderLayout.PAGE_START);
		contentPane.add(browserScrollPane, BorderLayout.CENTER);
		contentPane.add(statusLabel, BorderLayout.PAGE_END);
		
		getRootPane().setDefaultButton(goButton);
		
		//Create and set up the content pane.
        setJMenuBar(createMenuBar());
        
        //Init FileChooser for file opening
        fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
    }
    
    private JMenuBar createMenuBar() {
    	JMenuBar menuBar;
        JMenu menu;
        JMenuItem menuItem;

        //Create the menu bar.
        menuBar = new JMenuBar();

        //Build the File menu.
        menu = new JMenu("File");
        menu.setMnemonic(KeyEvent.VK_F);
        menu.getAccessibleContext().setAccessibleDescription(
                "File menu");
        menuBar.add(menu);

        //a group of JMenuItems
        menuItem = new JMenuItem("Open",
                                 KeyEvent.VK_O);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(
                KeyEvent.VK_1, ActionEvent.ALT_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription(
                "Opens file dialog");
        menuItem.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent e) {
        		int returnVal = fc.showOpenDialog(HTMLBrowserFrame.this);

                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    File file = fc.getSelectedFile();
                	openFile(file);
                    try {
						addressField.setText(file.getCanonicalPath());
					} catch (IOException e1) {}
                }
        	}
        });
        menu.add(menuItem);
        
        //a group of radio button menu items
        menu.addSeparator();
        
        menuItem = new JMenuItem("Close",
                KeyEvent.VK_Q);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(
        		KeyEvent.VK_2, ActionEvent.ALT_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription(
        		"Closes HTML browser");
        menuItem.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent e) {
        		System.exit(0);
        	}
        });
        menu.add(menuItem);
        
        //Build the Tools menu.
        menu = new JMenu("Tools");
        menu.setMnemonic(KeyEvent.VK_T);
        menu.getAccessibleContext().setAccessibleDescription(
                "Tools menu");
        menuBar.add(menu);
        
        menuItem = new JMenuItem("DOM tree",
                KeyEvent.VK_D);
		menuItem.setAccelerator(KeyStroke.getKeyStroke(
		KeyEvent.VK_1, ActionEvent.ALT_MASK));
		menuItem.getAccessibleContext().setAccessibleDescription(
		"Opens DOM tree");
		menuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				domTreeFrame.setVisible(true);
			}
		});
		menu.add(menuItem);
        
        return menuBar;
    }
    
	public void actionPerformed(ActionEvent e) {
		String address = addressField.getText();
		
		if (address != "") {
			try {
				URL url = new URL(address);
				System.err.println("Openning URL: " + address);
				openURL(url);
			} catch (MalformedURLException e1) {
				System.err.println("Openning file: " + address);
				openFile(new File(address));
			}
		}
	}
	
	private void openFile(File file) {
		try {
			if (file.exists()) {
				System.out.println("Set page file: " + file.getCanonicalPath());
				browserPane.setPage("file:/" + file.getCanonicalPath());
				addressField.setText("file:/" + file.getCanonicalPath());
			}
			else {
				browserPane.setPage("file:/" + System.getProperty("user.dir") + "\\errors\\404.html");
			}
		} catch (IOException e) {}
	}
	
	private void openURL(URL url) {
		try {
			System.out.println("Set page URL: " + url.toString());
			browserPane.setPage(url);
			addressField.setText(url.toString());
		} catch (IOException e) {
			try {
				browserPane.setPage("file:/" + System.getProperty("user.dir") + "\\errors\\404.html");
			} catch (IOException e1) {}
		}
	}
	
	public void hyperlinkUpdate(HyperlinkEvent evt) {
		if (evt.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
			URL currentURL = evt.getURL();
			
			//System.out.println("browserPane protocol: " + browserPane.getPage().getProtocol());
			
			if (currentURL != null) {
				System.out.println("Opening URL: " + currentURL.toString());
				addressField.setText(currentURL.toString());
				openURL(currentURL);
			}
			else if (browserPane.getPage().getProtocol().equals("http")) {
				try {
					String oldPath = browserPane.getPage().toString();
					String currentPath = oldPath.substring(0, oldPath.lastIndexOf("/") + 1) + evt.getDescription();
					System.out.println("Opening URL: " + currentPath);
					currentURL = new URL(currentPath);
					addressField.setText(currentURL.toString());
					openURL(currentURL);
				} catch (MalformedURLException e) {}
			}
			else {
				String path = evt.getDescription();
				File currentFile = new File(path);
				if (currentFile.exists()) {
					addressField.setText(path);
					openFile(currentFile);
				}
				else {
					try {
						String parentPath = new File(
								browserPane.getPage().getFile()
							).getParentFile().getCanonicalPath(); 
						currentFile = new File(
								new File(parentPath),
								path);
						
						addressField.setText(parentPath + System.getProperty("file.separator") + path);
						openFile(currentFile);
					} catch (IOException e) {}
				}
			}
			statusLabel.setText(browserPane.getPage().getProtocol());
		}
		else if (evt.getEventType() == HyperlinkEvent.EventType.ENTERED) {
			statusLabel.setText(evt.getDescription());
		}
		else if (evt.getEventType() == HyperlinkEvent.EventType.EXITED) {
			statusLabel.setText("");
		}
	}
	
	static final long serialVersionUID = 0x0001;
}
